iT邦幫忙

2022 iThome 鐵人賽

DAY 24
0
Modern Web

剛接觸前端一個月的小白 - JavaScript30 挑戰筆記系列 第 24

JS30 -> 25 - Event Capture, Propagation, Bubbling and Once

  • 分享至 

  • xImage
  •  

25 - Event Capture, Propagation, Bubbling and Once

tags: JavaScript30

專案簡介

第二十五天要學習的是 JS 中的 Capture、Propagation、Bubbling、Once

課程影片:JS30 25
導讀影片:Alex

初始文件

Github 檔案位置:25 - Event Capture, Propagation, Bubbling and Once

網站的樣子

正式製作

今天要做的事情是理解 Event Bubbling 和 Event Capturing 的差別

在 HTML 的 body 中有三個層層包裹的 div 元素,如下
分別以紫色、奶白色、橘色做區分

<body class="bod">
  <div class="one">
    <div class="two">
      <div class="three">
      </div>
    </div>
  </div>
<!-- .... -->

這裡先幫他們加入點擊事件監聽

const divs = document.querySelectorAll('div');

function logText(e) {
  console.log(this.classList.value);
}

divs.forEach(div => div.addEventListener('click', logText);

可以發現的是,當點擊最內層的元素時,其餘兩層的元素也會監聽到點擊事件,這是因為 addEventListener() 預設使用 JS 中的 Bubbling 冒泡事件,此事件會由內而外傳遞點擊事件,在範圍內有監聽點擊事件的函式都會觸發(會傳遞到 body 但 body 沒有監聽事件)

如果我們想避免這個現象的話可以使用 stopPropagation(),他可以阻止事件的傳遞

function logText(e) {
  console.log(this.classList.value);
  e.stopPropagation(); // 停止冒泡
}

另外,與由內向外相反的事件是 capturing,他會由外向內傳遞事件,這個可以設定在 addEventListener() 中的第三個參數

備註:capture 預設為 false,就是冒泡事件
備註:once 屬性是指事件只會觸發一次(觸發後再點擊就沒用了)

divs.forEach(div => div.addEventListener('click', logText, {
  capture: true,
  once: true
}));

點擊內層後就能發現他的順序顛倒了,變成外層 > 中層 > 內層

最後程式碼

const divs = document.querySelectorAll('div');
const button = document.querySelector('button');

function logText(e) {
  console.log(this.classList.value);
  // e.stopPropagation(); // 停止冒泡事件
}

divs.forEach(div => div.addEventListener('click', logText, {
  capture: true,
  once: true
}));

完成結果

請點開 Console
最後的成品

結語

以上是第二十五天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<

JavaScript Event Capture, Propagation and Bubbling - #JavaScript30 25/30
[ Alex 宅幹嘛 ] ?‍? 深入淺出 Javascript30 快速導覽 | Day 25:Event Related
MDN Web Docs


上一篇
JS30 -> 24 - Sticky Nav
下一篇
JS30 -> 26 - Stripe Follow Along Nav
系列文
剛接觸前端一個月的小白 - JavaScript30 挑戰筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言